Blog Top          Mijinko Semi Top

Mijinko seminar. Produced By SP

Now the Mijinko it is possible to stand up!!('A`)

	

多重起動3(EnumWindows、その他の多重起動について)

	いよいよ多重起動の授業も最後となるが、今回お前らに教える EnumWindows API を用いた多重起動は
	他の方法に比べてシステムへの負担が多くかかることもあり、多重起動をチェックすることだけにスポットを当てた場合、
	はっきりいって実用的ではない方法だ。
	
	そうだな、多重起動1で教えた FindWindow による多重起動 があるだろう。
	FindWindow はウィンドウタイトルを指定し、それと一致するものがあった場合に応答する API だ。
	それに比べて今回の EnumWindows はデスクトップ上の全てのトップレベルウィンドウの数だけ否応なしに処理をする API だ。
	
	さておき MSDN でさっさと確認するとしよう。
	
	
	-- MSDN より抜粋 --
	
	EnumWindows
	画面上のすべてのトップレベルウィンドウを列挙します。
	この関数を呼び出すと、各ウィンドウのハンドルが順々にアプリケーション定義のコールバック関数に渡されます。
	EnumWindows 関数は、すべてのトップレベルリンドウを列挙し終えるか、またはアプリケーション定義のコールバック関数から 
	0(FALSE)が返されるまで処理を続けます。
	
	BOOL EnumWindows(
	WNDENUMPROC lpEnumFunc,  // コールバック関数
	LPARAM lParam            // アプリケーション定義の値
	);
	
	パラメータ
	lpEnumFunc 
	アプリケーション定義のコールバック関数へのポインタを指定します。詳細については、EnumWindowsProc 関数の説明を参照してください。 
	lParam
	コールバック関数に渡すアプリケーション定義の値を指定します。
	
	------------------
	
	どうやら今回のターゲットとなる EnumWindows には2つの引数を指定する必要があるようだ。
	
	lpEnumFunc
	lParam
	
	それでは引数の説明にいくか。
	最初の引数は lpEnumFunc であるがその前に lParam の説明からいくぞ。
	これは説明文に書いてあるとおりコールバック関数に渡す値となる。
	この渡す値とはなにか?であるが、特にきまった値は無く、プログラムを作る側で勝手に決めていい値である。
	まぁ、ここらへんは深く考えずに補助的に使用するものだと捉えておけ。
	
	そして lpEnumFunc であるが、ここにはコールバック関数の場所を示す値(ポインタ)、もしくは名前を指定すればいいだけだ。
	
	さて、以上が EnumWindows の説明であるがこれだけでは多重起動のチェックなど到底実現できないのは分かるだろう。
	実際に肝心なのは EnumWindows ではなく、コールバック関数 のほうである。
	ではコールバック関数とはなんであろうか?
	
	これも MSDN から確認できる。というか EnumWindows のページにある EnumWindowsProc のリンク先が
	コールバック関数の説明ページだ。
	
	
	-- MSDN より抜粋 --
	
	EnumWindowsProc
	EnumWindows 関数または EnumDesktopWindows 関数から呼び出されるアプリケーション定義のコールバック関数です。
	この関数は、トップレベルウィンドウのハンドルを受け取ります。このコールバック関数へのポインタは、WNDENUMPROC 型として定義されています。
	EnumWindowsProc はアプリケーション定義の関数名のプレースホルダなので、コーディングでは実際に使う関数名に置き換えてください。
	
	BOOL CALLBACK EnumWindowsProc(
	HWND hwnd,      // 親ウィンドウのハンドル
	LPARAM lParam   // アプリケーション定義の値
	
	パラメータ
	hwnd 
	トップレベルウィンドウのハンドルが入ります。 
	
	lParam 
	EnumWindows 関数または EnumDesktopWindows 関数から渡されるアプリケーション定義の値が入ります。 	

	------------------
	
	ざっくりいうとコールバック関数は EnumWindows から呼び出される関数だ。
	EnumWindows はデスクトップ上に存在するトップレベルウィンドウを列挙し、ウィンドウの数だけコールバック関数を呼び出す。
	そしてコールバック関数は EnumWindows と同じく2つの引数を指定しなければならない。
	2つの引数は以下の通りである。
	
	hwnd
	lParam
	
	それでは hwnd の説明をするぞ。
	コールバック関数はウィンドウの数だけ呼ばれることになるが、呼ばれる度に hwnd にはデスクトップ上に存在するウィンドウの
	ウィンドウハンドラが順番に格納されていく。まぁ、実際に解析してみりゃすぐに動きが分かるからそんなに深く考えるな。
	
	次に lParam だ。
	こいつは説明するまでもないが、EnumWindows の引数で指定した lParam の値がそのまま渡されてくる。
	別に使いたくなけりゃ使わなくていい値だ。俺たちはあまり意識することはない代物だろうな。
	
	コールバック関数の引数の説明は以上となるが、こいつは API と違って内部に自由にプログラムを書くことが出来る。
	もちろん受け取れる引数は hwnd と lParam の2つだけであるが、多重起動のチェックをするにはこれだけで十分だ。
	
	それではちと早いがここで多重起動をチェックするロジックを教えるとするか。
	具体的にはコールバック関数の引数 hwnd の値を更に別の API へ渡すことで該当するウィンドウのウィンドウタイトルを引っ張りださせる。
	そして引っ張り出したウィンドウタイトルが自分自身のウィンドウタイトルと一致するか否かをチェックし、一致しなければそのままプログラムを
	立ち上げる。たったのこれだけだ。
	
	といってもこの説明だとコールバック関数の引数、hwnd の動きについては理解しづらいだろうな。
	しょうがないから例をあげて説明してやる。理解できたやつはいいが、わからんやつはちゃんと読んでおけよ。	
	
	例えばデスクトップ上に「ノートパッド」、「IE」、「電卓」、多重起動チェックの機能を持つプログラム「('A`)」の4つの
	ウィンドウが立ち上がっていたとする。
	その場合、EnumWindows およびコールバック関数は以下の流れで多重起動のチェックをする。
	
	1.EnumWindows はデスクトップ上に存在する 4つのウィンドウ(ノートパッド、IE、電卓、('A`) )を列挙し、その数(4)の分だけ
	  コールバック関数を呼び出す。
		
	2.1度目に呼び出されたコールバック関数の引数:hwnd には、まずノートパッドのウィンドウハンドラが格納され、引き続き
	  コールバック関数内部での処理が行われる。
	  そして 1度目のコールバック関数の処理が終わり、次に 2度目のコールバック関数が呼ばれるのだが、その際、引数:hwnd には
	  IE のウィンドウハンドラが格納される。(3度目も同じように hwnd には電卓、4度目には('A`)のウィンドウハンドラが格納される。)
	
	3.コールバック関数内部の処理では引数:hwnd を元に別の API を呼び出し、ウィンドウタイトルを調べる。
	  2度目のコールバック関数も同じように hwnd を元にウィンドウタイトルを調べていく。
	  
	4.もし、調べたウィンドウタイトルが自分の名前と同じものであれば、プログラムは既に起動していると判定しプログラムを終了させる。
	  そうでなければ、プログラムを立ち上げる。
	
	以上が多重起動をチェックするルーチンだ。
	念のためいっておくが、EnumWindows に呼ばれるコールバック関数はいずれも同じものだ。
	ただコールバック関数の引数である hwnd の値が呼ばれる度に入れ変わるだけだから勘違いするなよ。
	
	
	それではいよいよ解析を始めるが、ん?おいおい暖房切れてないか!?
	
	チッ、ポンコツめ・・・しょうがない、ここで10分の休憩にする。
	
	続きは隣の教室でやるから俺のために暖房つけて待っておけ。
	
		

	
	

Blog Top    Mijinko Semi Top

Copyright (C) 2006 SP-.SEESAA.NET - All Rights Reserved.